package com.brainhealth.customer.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.brainhealth.common.constant.CacheConstants;
import com.brainhealth.common.constant.Constants;
import com.brainhealth.common.constant.NumberConstants;
import com.brainhealth.common.core.redis.RedisCache;
import com.brainhealth.common.enums.TokenTypeEnum;
import com.brainhealth.common.utils.DateUtils;
import com.brainhealth.common.utils.NumberUtils;
import com.brainhealth.common.utils.StringUtils;
import com.brainhealth.common.utils.http.HttpUtils;
import com.brainhealth.customer.service.IErnieBotService;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Service
public class ErnieBotServiceImpl implements IErnieBotService {

    /**
     * 日志
     */
    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${ernieboot.apiKey:5V5nQvocOqVvXXaWxCELcgjE}")
    String apiKey;

    @Value("${ernieboot.sercretKey:2WEmXGpG8NQnZiGZfysEXVR49njEKbmc}")
    String secretKey;

    @Autowired
    RedisCache redisCache;

    @Override
    public String getAccessToken() {
        try {
            MediaType mediaType = MediaType.parse("application/json");
            RequestBody body = RequestBody.create(mediaType, "");
            String url="https://aip.baidubce.com/oauth/2.0/token?client_id=" + apiKey + "&client_secret=" + secretKey + "&grant_type=client_credentials";
            Request request = new Request.Builder()
                    .url(url) //按官网要求填写你申请的key和相关秘钥
                    .method("POST", body)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Accept", "application/json")
                    .build();
            OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
            Response response = httpClient.newCall(request).execute();
            String s = response.body().string();
            JSONObject objects = JSONArray.parseObject(s);
            String msg = objects.getString("access_token");
            logger.info("ts:{}，获取文心一言对话，access_token:{}", msg);
            return msg;
        } catch (Exception e) {
            logger.error("获取鉴权签名异常", e);
            return null;
        }
    }

    @Override
    public String getErnieBotResult(JSONObject object) {
        if (null==object){
            return Constants.AI_DEFAULT_ANSWER;
        }
        Object result = object.get("result");
        if (null==result||"".equals(result)){
            return Constants.AI_DEFAULT_ANSWER;
        }
        return String.valueOf(result);
    }

    @Override
    public Long getTotalTokens(JSONObject object, TokenTypeEnum tokenTypeEnum) {
        if (null==object){
            return null;
        }
        Object usage = object.get("usage");
        Map map = (Map) usage;
        String tokenKey = tokenTypeEnum.getKey();
        //tokens总数
        Object totalTokens = map.get(tokenKey);
        return NumberUtils.toLong(totalTokens);
    }

    @Override
    public JSONObject getCompletion(String accessToken,String prompt) {
        String requestMethod = "POST";
        //post请求时格式
        String url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token=" + accessToken;
        //测试：访问聚合数据的地区新闻api
        HashMap<String, String> msg = new HashMap<>();
        msg.put("role", "user");
        msg.put("content", prompt);
        ArrayList<HashMap> messages = new ArrayList<>();
        messages.add(msg);
        HashMap<String, Object> requestBody = new HashMap<>();
        requestBody.put("messages", messages);
        //requestBody.put("stream", true);
        String outputStr = JSON.toJSONString(requestBody);
        JSON json = HttpUtils.httpRequest(url, requestMethod, outputStr, "application/json");
        JSONObject object=(JSONObject)json;
        return object;
    }

    @Override
    public Integer refreshToken() {
        long ts = DateUtils.getTimeMillis();
        logger.info("ts{}定时任务刷新缓存{}",ts,CacheConstants.TOKENS_ERNIE_BOT);
        Object cacheObject = redisCache.getCacheObject(CacheConstants.TOKENS_ERNIE_BOT);
        if (null==cacheObject || StringUtils.isBlank(String.valueOf(cacheObject))) {
            logger.warn("ts{}重新获取token===================================",ts);
            String accessToken = getAccessToken();
            if (StringUtils.isBlank(accessToken)) {
                logger.warn("ts{}从文心一言获取token为空",ts);
                return null;
            }else{
                redisCache.setCacheObject(CacheConstants.TOKENS_ERNIE_BOT,accessToken);
                logger.info("ts{}设置token{}到缓存{}",ts,accessToken,CacheConstants.TOKENS_ERNIE_BOT);
                cacheObject= redisCache.getCacheObject(CacheConstants.TOKENS_ERNIE_BOT);
                accessToken = String.valueOf(cacheObject);
                logger.info("ts{}获取缓存{}token{}",ts,CacheConstants.TOKENS_ERNIE_BOT,accessToken);
            }
        }else{
            logger.warn("ts{}使用原token===================================",ts);
            String accessToken = String.valueOf(cacheObject);
            logger.info("ts{}获取缓存{}token{}",ts,CacheConstants.TOKENS_ERNIE_BOT,accessToken);
        }
        return NumberConstants.ONE;
    }
}
